package com.ui;


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;

import com.db.DB;
import com.fs.FileInvoices;
import com.fs.FinalResult;
import com.fs.Util;

@SuppressWarnings("serial")
public class FileVsDBui extends JFrame {
	
	public static final String FIND_BUTTON_CAPTION = "Start";
	public static final String STOP_BUTTON_CAPTION = "Stop";
	public static final String STATUS_MESSAGE_READY = "Ready.";
	JTextArea textAreaResult = new JTextArea();
	JButton buttonFindStartStop = new JButton(FIND_BUTTON_CAPTION);
	JButton openResult = new JButton("View Report");
	JLabel statusBarLabel = new JLabel(STATUS_MESSAGE_READY);
	public String url;
	private boolean searchingActive = false;
	private TesterThread finderThread;

	public FileVsDBui() {
		this.setTitle("Invoice check");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new BorderLayout());
		JPanel searchDetailsPanel = new JPanel();
		searchDetailsPanel.setLayout(new GridLayout(2,2));
		JLabel labelFileName = new JLabel("First configure the init.properties file and then press " + FIND_BUTTON_CAPTION);
		searchDetailsPanel.add(labelFileName);
		topPanel.add(searchDetailsPanel, BorderLayout.NORTH);
		buttonFindStartStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				buttonFindStartStopPressed();
			}
		});
		openResult.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openResult();
			}
		});
		JRootPane rootPane = this.getRootPane();
	    rootPane.setDefaultButton(buttonFindStartStop);
	    topPanel.add(buttonFindStartStop, BorderLayout.SOUTH);
	    topPanel.add(openResult, BorderLayout.CENTER);
		this.setLayout(new BorderLayout());
		this.add(topPanel, BorderLayout.NORTH);
		textAreaResult.setEditable(false);
		JScrollPane textAreaScrollPane = new JScrollPane(textAreaResult);
		this.add(textAreaScrollPane, BorderLayout.CENTER);
		JPanel statusBar = new JPanel();
		statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED));
		statusBar.setLayout(new GridLayout());
		statusBar.add(statusBarLabel);
		this.add(statusBar, BorderLayout.SOUTH);
		this.setSize(new Dimension(400, 400));
		openResult.setVisible(false);
		this.setVisible(true);
	}

	protected void openResult() {
		
			String osName = System.getProperty("os.name");
			String[] browsers = { "google-chrome", "firefox", "opera",
				      "konqueror", "epiphany", "seamonkey", "galeon", "kazehakase", "mozilla" };
	         try {
	            if (osName.startsWith("Mac OS")) {
	               Class.forName("com.apple.eio.FileManager").getDeclaredMethod(
	                  "openURL", new Class[] {String.class}).invoke(null,
	                  new Object[] {url});
	               }
	            else if (osName.startsWith("Windows"))
	               Runtime.getRuntime().exec(
	                  "rundll32 url.dll,FileProtocolHandler " + url);
	            else { //assume Unix or Linux
	               boolean found = false;
	               for (String browser : browsers)
	                  if (!found) {
	                     found = Runtime.getRuntime().exec(
	                        new String[] {"which", browser}).waitFor() == 0;
	                     if (found)
	                        Runtime.getRuntime().exec(new String[] {browser, url});
	                     }
	               }
	         } catch (Exception e) {
	        	 
	         }
	         getRootPane().setDefaultButton(buttonFindStartStop);
			
	}

	private void buttonFindStartStopPressed() {
		if (!searchingActive) {
			startSearch();
		}
		else {
			finderThread.interrupt();
		}
	}
	
	private void startSearch() {
		searchingActive = true;
		openResult.setVisible(false);
		buttonFindStartStop.setText(STOP_BUTTON_CAPTION);				
		textAreaResult.setText("Begin.\n");
		finderThread = new TesterThread(this);
		finderThread.start();
	}

	void searchFinished() {
		searchingActive = false;
		if (finderThread.wasInterrupted()) {
			textAreaResult.append("Aborted.");
		}
		else {
			textAreaResult.append("End.");
		}
		statusBarLabel.setText(FileVsDBui.STATUS_MESSAGE_READY);
		buttonFindStartStop.setText(FIND_BUTTON_CAPTION);	
		openResult.setVisible(true);
		getRootPane().setDefaultButton(openResult);
	}

}

class TesterThread extends Thread {
	
	FileVsDBui fileFinderFrame;
	private boolean wasInterrupted;
	
	public TesterThread(FileVsDBui fileFinderFrame) {
		this.fileFinderFrame = fileFinderFrame;
	}
	
	public void run() {
		ArrayList<String> bans = new ArrayList<String>();
		wasInterrupted = false;
		displayStatus("Running...");
		displayText("Initializing the testing parameters.");
		Util.init(bans);
		displayText("Testing parameters initialized.");
		DB.init(Util.dbConnectionString, Util.dbUser, Util.dbPassword);
		File file = new File(Util.fileName);
		FileInvoices fi = new FileInvoices(file, bans);
		displayText("Comparing.");
		ArrayList<FinalResult> results = fi.start();
		displayText("Comparing finished.");
		displayText("Generating report.");
		fileFinderFrame.url = Util.report(results);
		displayText("Report generated.");
		
		searchFinished();
	}
	
	private void displayText(final String message) {
		final JTextArea textAreaResult = this.fileFinderFrame.textAreaResult; 
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				textAreaResult.append(new Date(System.currentTimeMillis()) + "\t" + message + "\n");
			}
		});
	}

	private void displayStatus(final String message) {
		final JLabel statusBarLabel = this.fileFinderFrame.statusBarLabel; 
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				statusBarLabel.setText(message);
			}
		});
	}
	
	private void searchFinished() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				fileFinderFrame.searchFinished(); 
			}
		});
	}
	
	public boolean wasInterrupted() {
		return wasInterrupted;
	}

}
